 /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package rules;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import types.ColoringInfo;
import types.ISudokuMatrix;
import utils.RuleHelper;

/**
 *
 * @author kostja
 */
public class ScanOtherColAndRow implements Rule {
/*Funktionsweise: Bei dieser Regel werden,ausgehend von einem leeren Feld den man besetzen möchte
  ,andere leere Felder in einem Quadrat untersucht (scanen vertikal,horizontal),
 * ob diese für eine bestimmte Zahl gesperrt werden können. Falls alle Felder (ausgenommen Ausgang)
 * für eine Zahl gesperrt werden, dann kann man diese Zahl in Ausgansfeld eintragen.
 * Natürlich wird als erstes Ausgansfeld selbst gescant.
 */
    int quadrat = 0;
    int numberOfMissedDigits = -1;
    public String getName() {
        return ScanOtherColAndRow.class.getSimpleName();
    }

    public String getPicName() {
        return "Bei dieser Regel werden ausgehend von einem leeren Feld, den man besetzen möchte"+
                ", andere leere Felder in einem Quadrat untersucht (d.h. scanen vertikal,horizontal)," +
                "ob diese für eine bestimmte Zahl gesperrt werden können. Falls alle Felder (ausgenommen Ausgangsfeld)" +
                "für eine gleiche Zahl gesperrt werden, dann kann man diese Zahl in Ausgansfeld eintragen." +
                "Natürlich wird als erstes Ausgansfeld selbst gescant.";
    }

    public boolean isApplicable(int row, int col, ISudokuMatrix matrix) {
        int digit;
        System.out.println("Trying to apply rule "+ this.getName()+ " for "+row+","+col);
        try {
            this.setQuadrat(row, col);
            Collection missedDigits = RuleHelper.getMissingdigitsInQuadratOrColOrRow(RuleHelper.getDigitsSameQuadrat(row, col, matrix));
            Iterator iter = missedDigits.iterator();
            int countMissedDigits=missedDigits.size();
            this.numberOfMissedDigits = missedDigits.size();
            while (iter.hasNext()){
                digit=(Integer)iter.next();
                if (!(RuleHelper.existsDigitInCol(digit,col,matrix) || RuleHelper.existsDigitInRow(digit,row,matrix))){
                    if (RuleHelper.checkOtherFieldsInBlockOfClosedForDigit(digit,row,col,matrix,countMissedDigits))
                        return true;
                }
            }
        } catch (Exception ex) {
            Logger.getLogger(ScanOtherColAndRow.class.getName()).log(Level.SEVERE, null, ex);
        }
     return false;
    }

    public int getWeight(int QuadratNumber) {

            if (QuadratNumber == 5) {
            return (5 + (numberOfMissedDigits*5)) * 2;
        } else
        {
            return (5 + (numberOfMissedDigits*6)) * 2;
        }
   
    }

    public int compareTo(Rule o) {
        if (this.getWeight(this.getQuadrat())<o.getWeight(o.getQuadrat()))
            return -1;
        else if (this.getWeight(this.getQuadrat())>o.getWeight(o.getQuadrat()))
            return 1;
        else
            return 0;
    }

    public void setQuadrat(int x, int y) throws Exception {

            this.quadrat = RuleHelper.calculateQuadratNumber(x, y);

    }

    public int getQuadrat() {
       return this.quadrat;
    }
    // Es werden immer alle Quadrate markiert, die mit dieser Methode überprüft werden könnten.
    public ColoringInfo getCheckedUnits(int x, int y, ISudokuMatrix matrix) {
        int qNr;
        Collection neighbourQNrHorizontal=new ArrayList();
        Collection neighbourQNrVertical=new ArrayList();
        Collection allNeighboursQNr=new ArrayList();
        ColoringInfo colInfo=new ColoringInfo();
        try {
            qNr = RuleHelper.calculateQuadratNumber(x, y);
            neighbourQNrHorizontal=RuleHelper.getHorizontalQuadratNeighbours(qNr);
            neighbourQNrVertical=RuleHelper.getVerticalQuadratNeighbours(qNr);
            allNeighboursQNr.addAll(neighbourQNrHorizontal);
            allNeighboursQNr.addAll(neighbourQNrVertical);
            colInfo.setBlocks(allNeighboursQNr);
            return colInfo;
        } catch (Exception ex) {
            Logger.getLogger(ScanOtherColAndRow.class.getName()).log(Level.SEVERE, null, ex);
        }
        return colInfo;
    }
}
